/*
 * Copyright 2007 National Bioinformatics Network
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package dgbgui.gui.widgets.visual.modeldriven;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.geom.Rectangle2D;
import java.util.Set;

import dgbgui.gui.widgets.Highlightable;
import dgbgui.gui.widgets.Widget;
import dgbgui.gui.widgets.layouts.Layout;
import dgbgui.gui.widgets.layouts.VerticalLayout;
import dgbgui.gui.widgets.visual.LabelWidget;
import dgbgui.gui.widgets.visual.RectangleBorder;
import dgbgui.gui.widgets.visual.RectangleWidget;
import dgbgui.modeldocument.AttributePrototype;
import dgbgui.modeldocument.ModelDocument;
import dgbgui.modeldocument.Query;
import dgbgui.modeldocument.QueryResult;
import dgbgui.modeldocument.ResultStore;
import dgbgui.modeldocument.definition.FilteredConceptDefinition;
import dgbgui.modeldocument.primitives.Concept;
import dgbgui.modeldocument.primitives.ConceptType;
import edu.umd.cs.piccolo.PNode;

@SuppressWarnings("serial")
public class ModelDrivenConceptWidget extends RectangleBorder implements Highlightable {
    
    public ModelDrivenConceptWidget(PNode parent, Concept concept, Query query, boolean isTarget) {
        super(parent,5.0,5.0);
        
        setFillColor(new Color(0,0,0,0));
        setStrokeColor(new Color(0,0,0,0));
        
        m_concept = concept;

        double radius = 5;
        double padding = 5;
        
        // The dummy layout for highlighting
        VerticalLayout layout = new VerticalLayout(this,5,5);
        
        // The visible border
        RectangleBorder border = new RectangleBorder(layout,5,5);
        border.setStrokeColor(Color.black);
        if ( isTarget) {
            border.setFillColor(new Color(255,200,200,255));
        } else {
            border.setFillColor(new Color(200,200,255,255));
        }
        
        
        // And now the layout for the vidible widgets
        VerticalLayout visibleLayout = new VerticalLayout(border,0,0);
        
        // Type
        ConceptType type = (ConceptType)ModelDocument.getInstance().getConceptronType(concept);
        
        RectangleBorder topBorder = new RectangleBorder(visibleLayout,radius,radius);
        Layout topLayout = new VerticalLayout(topBorder,padding,padding);
        new LabelWidget(topLayout,type.m_name);
        if ( isTarget) {
            topBorder.setFillColor(new Color(255,100,100));
        } else {
            topBorder.setFillColor(new Color(100,100,255));
        }
        
        // Description
        RectangleBorder bottomBorder = new RectangleBorder(visibleLayout,radius,radius);
        Layout bottomLayout = new VerticalLayout(bottomBorder,padding,padding);
        
        // If the node has a query, display that info, otherwise just display
        // how many
        boolean querySubmitted = ((query != null) && ResultStore.getInstance().hasBeenSubmitted(query));
        boolean hasResult = ((query != null) && ResultStore.getInstance().hasResult(query));
        if ( querySubmitted ){  
            if ( hasResult ) {
                QueryResult result = ResultStore.getInstance().getResult(query);
                String label = "" + result.getPrimitives().size() + " result";
                if ( result.getPrimitives().size() > 1 ) {
                    label += "s";
                }
                new LabelWidget(bottomLayout, label);
            } else {
                new LabelWidget(bottomLayout, "In progress...");
            }
        }
        else if ( query == null ) {
            //int count = ModelFactory.getInstanceCount(type.m_name);
            new LabelWidget(bottomLayout, "All instances");// [" + count + "]");//;
            
        } else if ( query.getDefinition() instanceof FilteredConceptDefinition) {
            FilteredConceptDefinition definition = (FilteredConceptDefinition)(query.getDefinition());
            assert(definition != null);
            Set<AttributePrototype> attribProtos = definition.getAttribProtoTypes();
            if ( attribProtos.size() == 0 ) {
                //int count = ModelFactory.getInstanceCount(definition.getConceptronType().m_name);
                new LabelWidget(bottomLayout, "All instances ");
            }
            else {
                for ( AttributePrototype attribProto : attribProtos ) {
                    new LabelWidget(bottomLayout, attribProto.toString());
                }
            }
        } else {
            new LabelWidget(bottomLayout,"?");
        }
        
        // No border, just 
        bottomBorder.setStrokeColor(new Color(0,0,0,0));
        bottomBorder.setFillColor(new Color(0,0,0,0));
    }

    public Concept getConcept() {
        return m_concept;
    }
    
    public String toString() {
        return ModelDocument.getInstance().getConceptronType(m_concept).m_name;
    }
    
    public void unhighlight() {
        setFillColor(m_originalFillColor);
        setStrokeColor(m_originalStrokeColor);
    }
    
    public void highlight() {
        // For highlighting, store the widget's own fill
        // colour, instead of using the colour that's inherited
        // since that same colour will be restored on unhighlighting
        // (the colour could also be null)
        m_originalFillColor = getOwnFillColour();
        m_originalStrokeColor = getOwnStrokeColour();
        setFillColor(Color.yellow);
    }
    
    
    private Widget drawAroundWidget(Color color) {
        Rectangle2D bounds = getFullBounds();
        Rectangle2D surround = new Rectangle2D.Double(
                bounds.getX(),
                bounds.getY(),
                bounds.getWidth(),
                bounds.getHeight());
        Widget w = new RectangleWidget((Widget)getParent(),surround,5.0,5.0);
        w.setStrokeColor(color);
        w.setStrokeStyle(new BasicStroke());
        w.setFillColor(new Color(0,0,0,0));
        w.moveInBackOf(this);
        return w;
    }
    

    public void showSelectable(Color color) {
        m_selectableRectangle = drawAroundWidget(color);
    }
    
    public void restoreSelectable() {
        m_selectableRectangle.removeFromParent();
    }
    

    // The fill color before highlighting
    Color m_originalFillColor;
    Color m_originalStrokeColor;

    // The concept for this widget
    Concept m_concept;
    
    // Rectangle for indicating selection
    Widget m_selectableRectangle = null;

}
